/**
 * 准备用这个类代替之前的geoTweenMoveTo
 */
var NodeUtils = require('geoUtils').node;

/**
 * 将一个物体从当前位置移动到目标位置
 * 可以设定多个目标，调用时指定索引号
 * [bugs] TweenMoveTo目前必须添加在要移动的目标身上，否则不奏效，不知道原因
 */
cc.Class({
    extends: cc.Component,

    properties: {
        target: {
            default: null,
            type: cc.Node,
            tooltip: '要控制的目标对象'
        },
        moveTos: {
            default: [],
            type: [cc.Node],
            tooltip: '目的位置，可以指定多个'
        },
        onStartIndex: {
            default: -1,
            type: cc.Integer,
            tooltip: '加载时放置在哪个位置，-1为不执行操作'
        },
        tweenActionTag: {
            default: 9001,
            type: cc.Integer,
            tooltip: '变换动作的标签，用于连续变换时停止之前的变换，同一个node上标签不要重复'
        },
        _inTween: {
            default: false,
            visible:false,
        }
    },

    // LIFE-CYCLE CALLBACKS:

    // onLoad () {},

    start() {

        // this._inTween = false;
        // this._cachedTween = {};
        
        if (this.onStartIndex >= 0 && this.onStartIndex < this.moveTos.length) {
            var dstNode = this.moveTos[this.onStartIndex];
            this.node.position = this._getDstPos(dstNode);
        }
    },
    /**
     * 获取操作目标
     */
    getTarget(){
        return this.target || this.node;
    },

    /**
     * 将目标在指定时间内移动到索引指定的目的地
     * @param {int} index 
     * @param {number} duration 
     * @param {Function} complete 指定移动结束后的回调
     */
    doTween(index, duration, complete, useMove, useScale, useRotation) {
        // 获取目的地坐标
        if (index < 0 && index >= moveTos.length)
            return;
        var dstNode = this.moveTos[index];
        this.doTweenToNode(dstNode, duration, complete, useMove, useScale, useRotation);

        // var dstPos = dstNode.position;
        // // 构建移动action
        // var moveAction = cc.moveTo(duration, dstPos);
        // // 处理回调
        // if (complete)
        //     this.getTarget().runAction(cc.sequence([moveAction,cc.callFunc(complete)]));
        // else
        //     this.getTarget().runAction(moveAction);
    },
    /**
     * 移动到一个目的node
     * @param {*} dstNode 
     * @param {*} duration 
     * @param {*} complete 
     * @param {bool} useScale 是否与dstNode的世界缩放保持一致
     * @param {bool} useRotation 是否与dstNode的世界旋转保持一致
     */
    doTweenToNode(dstNode, duration, complete, useMove, useScale, useRotation) {
        var position = null, rotation = null, scale = null;
        // 保持兼容
        if (useMove === void 0)
            useMove = true;

        if (useMove === true) {
            var dstPos = this._getDstPos(dstNode);
            position = dstPos;
        }

        if (useScale === true) {
            var dstScale = this._getDstScale(dstNode);
            scale = dstScale;
        }

        if (useRotation === true) {
            var dstRotation = this._getDstRotation(dstNode);
            rotation = dstRotation;
        }

        this.doTweenToValue(duration, position, scale, rotation, complete);
    },
    /**
     * 将目标节点的变换过渡到目的值（本地），
     * 不需要变换的方面可以留null
     * @param {float} duration 变换时长
     * @param {cc.Vec2} position 位置
     * @param {cc.Vec2} scale 缩放
     * @param {float} rotation 旋转
     * @param {function} complete 完成回调
     */
    doTweenToValue(duration, position, scale, rotation, complete){
        this._cachedTween = this._cachedTween || {};
        // 缓存tween参数，服务于pause和resume
        this._cachedTween['duration'] = duration;
        this._cachedTween['position'] = position;
        this._cachedTween['scale'] = scale;
        this._cachedTween['rotation'] = rotation;
        this._cachedTween['complete'] = complete;
        //
        this._timeInTween = 0;
        //
        return this._doTweenToValueInternal(duration, position, scale, rotation, complete)

    },
    _doTweenToValueInternal(duration, position, scale, rotation, complete){
        // 终止前面可能的tween
        this.stopTween();

        // 由于数组类action不能仅有一个元素，所以添加一个dummyAction充数
        var dummyAction = cc.callFunc(() => { });
        // 
        var spawnActions = [dummyAction, cc.delayTime(duration)];
        var finalActions = [];

        if (position != null) {
            spawnActions.push(cc.moveTo(duration, position));
        }

        if (scale != null) {
            spawnActions.push(cc.scaleTo(duration, scale.x, scale.y));
        }

        if (rotation != null) {
            spawnActions.push(cc.rotateTo(duration, rotation));
        }

        finalActions.push(cc.spawn(spawnActions));

        // if (complete) {
        //     finalActions.push(cc.callFunc(complete));
        // } else {
        //     finalActions.push(dummyAction);
        // }

        finalActions.push(cc.callFunc((()=>{
            this._inTween = false;
            this._timeInTween = 0;
            this._cachedTween = null;
            //
            complete && complete();
        }).bind(this)));
        
        var tweenAction = cc.sequence(finalActions);
        tweenAction.setTag(this.tweenActionTag);

        this._inTween = true;

        return this.getTarget().runAction(tweenAction);

    },
    /**
     * 停止当前的动作
     */
    stopTween(){
        this._inTween = false;
        //
        this.getTarget().stopActionByTag(this.tweenActionTag);
    },
    /**
     * 暂停动作
     */
    pauseTween(){
        if (this._inTween !== true)
            return;
        //
        this._inTween = false;
        this._paused = true;
        //
        this.getTarget().stopActionByTag(this.tweenActionTag);
    },
    /**
     * 恢复动作
     */
    resumeTween(){
        if (this._paused !== true)
            return;
        this._paused = false;
        //
        var cached = this._cachedTween;
        var duration = cached['duration'] - this._timeInTween;
        return this._doTweenToValueInternal(
            duration,
            cached['position'],
            cached['scale'],
            cached['rotation'],
            cached['complete']
        );
    },
    /**
     * 直接放置到一个节点位置
     * @param {*} dstNode 
     */
    setToNode(dstNode, useMove, useScale, useRotation) {
        var position = null, rotation = null, scale = null;
        
        this.getTarget().stopActionByTag(this.tweenActionTag);
        // 兼容之前的使用
        if (useMove === void 0)
            useMove = true;

        if (useMove === true)
        position = this._getDstPos(dstNode);
        if (useScale === true) {
            scale = this._getDstScale(dstNode);
        }
        if (useRotation === true) {
            rotation = this._getDstRotation(dstNode);
        }

        this.setToValue(position, scale, rotation);

    },
    /**
     * 设置目标节点的变换（本地）
     * 不需要设置的方面可以留null
     * @param {cc.Vec2} position 
     * @param {cc.Vec2} scale 
     * @param {float} rotation 
     */
    setToValue(position, scale, rotation) {
        if (position != null)
            this.getTarget().position = position;
        if (scale != null) {
            this.getTarget().scaleX = scale.x;
            this.getTarget().scaleY = scale.y;
        }
        if (rotation != null){
            this.getTarget().rotation = rotation;
        }
    },
    /**
     * 直接放置到索引确定的节点位置
     * @param {*} index 
     */
    setToIndex(index, useMove, useScale, useRotation) {
        var dstNode = this.moveTos[index];
        if (dstNode)
            this.setToNode(dstNode, useMove, useScale, useRotation);
    },
    _getDstPos(dstNode) {
        // 获取目的地坐标
        // var dstPos = dstNode.position;
        var dstPos = NodeUtils.getWorldPosition(dstNode);
        dstPos = NodeUtils.getWorldToNodePosition(this.getTarget().parent, dstPos);

        // dstPos = dstNode.parent.convertToWorldSpaceAR(dstPos);
        // dstPos = this.getTarget().parent.convertToNodeSpaceAR(dstPos);

        return dstPos;
    },
    _getDstScale(dstNode) {
        
        // var dstScale = this._getNodeToWorldScale(dstNode, dstNode.scaleX, dstNode.scaleY);
        var dstScale = NodeUtils.getWorldScale(dstNode);
        dstScale = NodeUtils.getWorldToNodeScale(this.getTarget().parent, dstScale.x, dstScale.y);
        // dstScale = this._getWorldToNodeScale(this.getTarget().parent, dstScale.x, dstScale.y);

        return dstScale;
    },
    _getDstRotation(dstNode) {
        // var dstRotation = this._getNodeToWorldRotation(dstNode, dstNode.rotation);
        var dstRotation = NodeUtils.getWorldRotation(dstNode);
        dstRotation = NodeUtils.getWorldToNodeRotation(this.getTarget().parent, dstRotation);
        // dstRotation = this._getWorldToNodeRotation(this.getTarget().parent, dstRotation);

        return dstRotation;
    },
    /**
     * 是否处于动作过程中
     */
    isInTween(){
        return this._inTween;
    },
    update(dt){
        if (this.isInTween() === true) {
            // 若处于播放状态，累计播放时间
            this._timeInTween += dt;
        }
    },
});